package com.ymt.bpm.appboot;

import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

/**
 * Created by Johnny on 2016/12/29.
 */
@Configuration
@EnableConfigurationProperties(value={MybatisProperties.class, DruidDataSourceConfig.class})
@ConfigurationProperties(prefix = "mybatisplugin")
public class MybatisConfig {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MybatisProperties properties;

    /**
     * database dialect
     */
    private String dialect;

    @Autowired
    private DruidDataSourceConfig druidDataSourceConfig;

    @Bean
    public DataSource dataSource() {
        logger.info("druidDataSourceConfig" + druidDataSourceConfig);
        logger.info("Bean >>> DruidDataSource dataSource");
        // 加载配置文件属性
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(druidDataSourceConfig.getDriverClassName());
        ds.setUsername(druidDataSourceConfig.getUsername());
        ds.setPassword(druidDataSourceConfig.getPassword());
        ds.setUrl(druidDataSourceConfig.getUrl());
        ds.setMaxActive(druidDataSourceConfig.getMaxActive());
        ds.setValidationQuery(druidDataSourceConfig.getValidationQuery());
        ds.setTestOnBorrow(druidDataSourceConfig.isTestOnBorrow());
        ds.setTestOnReturn(druidDataSourceConfig.isTestOnReturn());
        ds.setTestWhileIdle(druidDataSourceConfig.isTestWhileIdle());
        ds.setTimeBetweenEvictionRunsMillis(druidDataSourceConfig.getTimeBetweenEvictionRunsMillis());
        ds.setMinEvictableIdleTimeMillis(druidDataSourceConfig.getMinEictableIdleTimeMillis());
        ds.setPoolPreparedStatements(druidDataSourceConfig.isPoolPreparedStatements());
        ds.setMaxOpenPreparedStatements(druidDataSourceConfig.getMaxOpenPreparedStatements());
        try {
            ds.setFilters(druidDataSourceConfig.getFilters());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ds;
    }


    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        logger.info("Bean >>> SqlSessionFactory sqlSessionFactory");

        final SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource());
        factory.setVfs(SpringBootVFS.class);
        /*if (StringUtils.hasText(this.properties.getConfigLocation())) {
            factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
        }*/
        factory.setConfiguration(properties.getConfiguration());

        if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
            factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        }
        if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
            factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
        }
        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
            factory.setMapperLocations(this.properties.resolveMapperLocations());
        }

        logger.info("sqlSessionFactory adding pagehelper plugin...");
        //配置mybatis 分页插件
        PageHelper pageHelper=new PageHelper();
        Properties phProperties = new Properties();
        phProperties.setProperty("dialect", this.dialect);
        phProperties.setProperty("params","pageNum=start;pageSize=limit;pageSizeZero=zero;reasonable=false;count=contsql");
        pageHelper.setProperties(phProperties);
        factory.setPlugins(new Interceptor[]{pageHelper});

        return factory.getObject();
    }

    @Bean
    public DataSourceTransactionManager transactionManager() {
        logger.info("Bean >>> DataSourceTransactionManager transactionManager");
        return new DataSourceTransactionManager(dataSource());
    }


    @PostConstruct
    public void postConstruct() {
        logger.info("postConstruct", druidDataSourceConfig);
    }

    public Resource[] getResource(String basePackage, String pattern) throws IOException {
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(new StandardEnvironment().resolveRequiredPlaceholders(basePackage)) + "/" + pattern;
        Resource[] resources = new PathMatchingResourcePatternResolver().getResources(packageSearchPath);
        return resources;
    }

    public void setDialect(String dialect) {
        this.dialect = dialect;
    }

}
